package com.vincce.fitness.core.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Pattern;


/**
 * 处理时间的工具类
 * Created by ThinkPad User on 2014/5/9.
 */
public final class DateTimeUtil
{

	/**
	 * 获得当前的系统时间
	 * 
	 * @return 当前的系统日期
	 */
	public static Date getCurrentTime()
	{
		return new Date();
	}

	/**
	 * 获得当前的系统日期，不带有时分秒
	 * 
	 * @return 当前的系统日期
	 */
	public static Date getCurrentDate()
	{

		Date date = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.clear(Calendar.MINUTE);
		c.clear(Calendar.SECOND);
		c.clear(Calendar.MILLISECOND);

		date = c.getTime();
		return date;
	}

    public static Date getCD()
    {

        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        c.clear(Calendar.MILLISECOND);

        date = c.getTime();
        return date;
    }

	/**
	 * 根据字符串格式日期，返回Date
	 * 
	 * @param d
	 *            Date
	 * @return 当前的系统日期
	 */
	public static Date getDate(String d)
	{
		Timestamp ts = Timestamp.valueOf(d);
		return ts;
	}



	/**
	 * 输出字符串类型的格式化日期
	 * 
	 * @param dt
	 *            Date
	 * @param pattern
	 *            时间格式
	 * @return sDate
	 */
	public static String getFormatDate(Date dt, String pattern)
	{
		String sDate;
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		sDate = formatter.format(dt);
		return sDate;
	}


	/**
	 * 得到指定日期的月份,格式：yyyy-mm-dd
	 * 
	 * @return String
	 */
	public static String getDateMonth(Date date)
	{

		SimpleDateFormat format1 = new SimpleDateFormat("yyyy'-'MM'-'dd");
		format1.setLenient(false);
		String dateStr = format1.format(date);
		int begin = dateStr.indexOf('-') + 1;
		int end = dateStr.lastIndexOf('-');
		String month = dateStr.substring(begin, end);
		return month;
	}

	/**
	 * 得到某一天的开始时间，精确到毫秒
	 * 
	 * @param date
	 *            日期
	 * @return 某一天的0时0分0秒0毫秒的那个Date
	 */
	public static Date beginOfDay(Date date)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		date = c.getTime();
		return date;
	}


    /**
     * 得到指定日期后若干小时的日期
     *
     * @param date
     *            指定日期
     * @param hours
     *            小时数
     * @return 自指定日期后的若干天的日期
     */
    public static Date afterHoursSinceDate(Date date, int hours)
    {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR, hours);
        date = c.getTime();
        return date;
    }

	/**
	 * 得到指定日期后若干天的日期
	 * 
	 * @param date
	 *            指定日期
	 * @param days
	 *            天数
	 * @return 自指定日期后的若干天的日期
	 */
	public static Date afterDaysSinceDate(Date date, int days)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, days);
		date = c.getTime();
		return date;
	}

    /**
     * 得到指定日期后若干天的日期
     * @param date      指定日期
     * @param years     天数
     * @return          自指定日期后的若干天的日期
     */
    public static Date afterYearsSinceDate(Date date,int years){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR,years);
        date = c.getTime();
        return date;
    }
    /**
     * 得到指定日期后若干月的日期
     * @param date      指定日期
     * @param months     天数
     * @return          自指定日期后的若干天的日期
     */
    public static Date afterMonthsSinceDate(Date date,int months){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH,months);
        date = c.getTime();
        return date;
    }


	/**
	 * 判断两个Date是否在同一天
	 * 
	 * @param date1
	 *            date1
	 * @param date2
	 *            date2
	 * @return 如果两个Date在同一天，则返回true，否则false
	 */
	public static boolean isTwoDatesInSameDay(Date date1, Date date2)
	{
		Date preDate1 = preDay(date1);
		Date nextDate1 = nextDay(date1);
		if (date2.after(preDate1) && date2.before(nextDate1))
		{
			return true;
		}
		return false;
	}

	/**
	 * 得到指定日期的下一天的开始时间
	 * 
	 * @param date
	 *            指定Date
	 * @return 下一天的开始时间
	 */
	public static Date beginOfNextDay(Date date)
	{
		date = nextDay(date);
		return beginOfDay(date);
	}

	/**
	 * 得到指定日期的下一天
	 * 
	 * @param date
	 *            日期
	 * @return 传入日期的下一天
	 */
	public static Date nextDay(Date date)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, 1);
		date = c.getTime();
		return date;
	}

	/**
	 * 得到指定日期的前一天
	 * 
	 * @param date
	 *            日期
	 * @return 传入日期的前一天
	 */
	public static Date preDay(Date date)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DATE, -1);
		date = c.getTime();
		return date;
	}

	/**
	 * 得到当前月份的下一个月份
	 * 
	 * @return String
	 */
	public static Date addMonth(Date date)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 1);
		date = c.getTime();
		return date;
	}


	/**
	 * 得到当前月的最后一天
	 * 
	 * @return String
	 */
	public static Date getLastDayOfMonth(Date date)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH, 1);
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.add(Calendar.DAY_OF_MONTH, -1);
		date = c.getTime();
		return date;
	}

	/**
	 * 得到当前月的第一天
	 * 
	 * @return String
	 */
	public static Date getFirstDayOfMonth(Date date)
	{
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, 1);
		date = c.getTime();
		return date;
	}

	/**
	 * 判断一个日期是否在指定的时间段内
	 * 
	 * @return String
	 */
	public static boolean inTimeSegment(Date start, Date end, Date date)
	{
		start = preDay(start);
		end = nextDay(end);
		if (date.after(start) && date.before(end))
		{
			return true;
		}
		return false;
	}

	/**
	 * 判断当前日期是否在指定的时间段内
	 * 
	 * @param start
	 *            时间段开始时间
	 * @param end
	 *            时间段结束时间
	 * @return 如果当前日期在指定时间段内，则为true，否则为false
	 */
	public static boolean isCurrentDateInTimeSegment(Date start, Date end)
	{
		Date date = getCurrentDate();
		if (inTimeSegment(start, end, date))
		{
			return true;
		}
		return false;
	}

	/**
	 * 得到同一个月内两个日期的间隔天数 备注：可能需要提交到框架作统一处理
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static int betweenDaysInOneMonth(Date start, Date end)
	{
		String startStr = getFormatDate(start, "yyyyMMdd");
		String endStr = getFormatDate(end, "yyyyMMdd");
		int days = Integer.parseInt(endStr) - Integer.parseInt(startStr) + 1;
		return days;
	}

	/**
	 * 得到两个日期的间隔天数
	 * @param start
	 * @param end
	 * @return -1说明开始日期大于结束日期
	 */
	public static int getBetweenDays(Date start, Date end)
	{
		if (start.after(end))
		{
			return -1;
		}
		Calendar startC = Calendar.getInstance();
		startC.setTime(start);
		Calendar endC = Calendar.getInstance();
		endC.setTime(end);
		endC.add(Calendar.DAY_OF_YEAR, 1);
		int days = 0;
		do
		{
			days++;
			startC.add(Calendar.DAY_OF_YEAR, 1);
		} while (startC.before(endC));
		return days-1;
	}

	/**
	 * 得到指定月份的天数
	 * 
	 * @param date
	 * @return
	 */
	public static int daysInMonth(Date date)
	{
		Date start = getFirstDayOfMonth(date);
		Date end = getLastDayOfMonth(date);
		int days = betweenDaysInOneMonth(start, end);
		return days;
	}

	/**
	 * 判断两个时间段是否存在重叠
	 * 
	 * @param start1
	 *            第一个时间段的开始时间
	 * @param end1
	 *            第一个时间段的结束时间
	 * @param start2
	 *            第二个时间段的开始时间
	 * @param end2
	 *            第二个时间段的结束时间
	 * @return 如果存在重叠返回true，否则false
	 */
	public static boolean isTimeOverlap(Date start1, Date end1, Date start2,
			Date end2)
	{
		if (inTimeSegment(start1, start2, end2)
				|| inTimeSegment(end1, start2, end2))
		{
			return true;
		}
		return false;
	}

	/**
	 * 把传入的时间和当前的系统时间进行比较，精度控制在天。
	 * 
	 * @param formmartTimeString 格式为yyyyMMdd
	 *            格式化的时间字符串 年月日 ********8位的字符串
	 * @return comparedResult 1 传入的时间大于系统当前时间，0相等，-1是小于。
	 */
	public static int compareCurrentTime(String formmartTimeString)
	{
		// TODO 得到当前系统的时间函数需要变更
		Calendar currentTime = Calendar.getInstance();
		Calendar comparedTime = (Calendar) currentTime.clone();
		comparedTime.set(Calendar.YEAR, Integer.parseInt(formmartTimeString
				.substring(0, 4)));
		comparedTime.set(Calendar.MONTH, Integer.parseInt(formmartTimeString
				.substring(4, 6)) - 1);
		comparedTime.set(Calendar.DAY_OF_MONTH, Integer
				.parseInt(formmartTimeString.substring(6, 8)));
		int comparedResult = comparedTime.compareTo(currentTime);
		return comparedResult;
	}

	public static Date getDateFromFormattingString(String dateString)
	{
		Calendar currentTime = Calendar.getInstance();
		currentTime.set(Calendar.YEAR, Integer.parseInt(dateString.substring(0,
				4)));
		currentTime.set(Calendar.MONTH, Integer.parseInt(dateString.substring(
				5, 7)) - 1);
		currentTime.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateString
				.substring(8, 10)));
		currentTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateString
				.substring(11, 13)));
		currentTime.set(Calendar.MINUTE, Integer.parseInt(dateString.substring(
				14, 16)));
		currentTime.set(Calendar.SECOND, Integer.parseInt(dateString.substring(
				17, 19)));
		return currentTime.getTime();
	}

	public static Date getFormatDate(String str) throws ParseException
	{
		if (str == null || "".equals(str))
			return null;
		if (str.length() <= 10)
		{
			return getDateByString(str, "yyyy-MM-dd");
		} else
		{
			return getDateByString(str, "yyyy-MM-dd HH:mm");
		}
	}

	public static Date getDateByString(String str, String pattern)
			throws ParseException
	{
		SimpleDateFormat df3 = new SimpleDateFormat();
		df3.applyPattern(pattern);
		return df3.parse(str);
	}

	public static Date addDate(Date date, int num)
	{
		return new Date(date.getTime() + num * (long) 24 * 3600 * 1000);
	}

    public static Date minDate(Date date, int num)
    {
        return new Date(date.getTime() - num * (long) 24 * 3600 * 1000);
    }


    /**
     * 符合本业务的获取时间方法,通过年月日小时生成时间
     *
     * @param date
     * @param hour
     * @return
     * @throws java.text.ParseException
     */
    public static Date createDate(Date date, Long hour)
    {
    	Date result = null;
    	if (date != null)
    	{
			try {
				result = new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(date));
			} catch (ParseException e) {
				e.printStackTrace();
			}
    	}
        if (result != null && hour != null)
        {
            result.setHours(hour.intValue());
        }
        return result;
    }

    /**
     * 符合本业务的获取时间方法,通过年月日小时生成时间
     *
     * @param date
     * @param hour
     * @return
     * @throws java.text.ParseException
     */
    public static Date createDate(Date date, Long hour, Long minute)
    {
    	Date result = null;
    	if (date != null)
    	{
			try {
				result = new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(date));
			} catch (ParseException e) {
				e.printStackTrace();
			}
    	}
        if (result != null )
        {
            if(hour != null)
                result.setHours(hour.intValue());
            if(minute != null)
                result.setMinutes(minute.intValue());
        }
        return result;
    }

    /**
     * SQL语句小于时间的转换 比如小于1月1日，sql语句中其实是小于1月2日
     *
     * @param resourceDate
     * @return
     */
    public static Date getSqlLessDate(Date resourceDate)
    {
        Calendar c = Calendar.getInstance();
        c.setTime(resourceDate);
        c.add(Calendar.DATE, 1);
        c.clear(Calendar.HOUR);
        c.clear(Calendar.MINUTE);
        c.clear(Calendar.SECOND);
        c.clear(Calendar.MILLISECOND);
        return c.getTime();
    }
    

    /**
     * 在一个日期推后 days 天 的日期，不包含星期六和星期天
     * @param date
     * @param days
     * @return
     */
    public static Date addDateIgnoreSaturdaySunday(Date date, long days)
    {
        if (date != null)
        {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            for (int i = 0; i < days;)
            {
                c.add(Calendar.DATE, 1);
                if (c.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && c.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY)
                {
                    i ++;
                }
            }
            date = c.getTime();
        }
        return date;

    }


    public static int getAge(Date birthDay) throws Exception {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) {
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);

        cal.setTime(birthDay);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                //monthNow==monthBirth
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                //monthNow>monthBirth
                age--;
            }
        }
        return age;
    }


	/**
	 * 得到指定月的第一天
	 * @param date
	 * @param months
	 * @return
	 */
	public static Date getMonthsDate(Date date,int months) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.MONTH,months);
		c.set(Calendar.DAY_OF_MONTH, 1);
		date = c.getTime();
		return date;
	}

    /**校验手机号*/
    public static boolean isMobile(String mobile){
        String mob="^0?(13[0-9]|15[012356789]|18[0236789]|14[57]|170)[0-9]{8}$";
        String mob1="^[\\S\\d]{7,}$";
                //"^\\d{7,11}$";
               // "^([\\S\\d]*){7,11}$";
        boolean flag =true;
        if(mobile.length()>0){
            flag=Pattern.compile(mob1).matcher(mobile).matches();
        }
       /* if(mobile.length()==11){
            flag = Pattern.compile(mob).matcher(mobile).matches();
        }*/
        return flag;
    }


	/**
	 * 获取指定时间的前或后分钟内时间
	 * @param date
	 * @param num
	 * @return
	 */
	public static Date getPreOrNex(Date date,int num){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE,num);
		return cal.getTime();
	}

    public static void main(String[] args) throws ParseException {
       /* System.out.println(afterDaysSinceDate(new Date(), -30));
		System.out.println(isTwoDatesInSameDay(new Date(), afterDaysSinceDate(new Date(), 0)));
		System.out.println(getBetweenDays(new Date(),afterDaysSinceDate(new Date(), 4)));*/
		/*Date idCardBirth = DateTimeUtil.getDateByString(IdCardUtil.getBirthByIdCard("340621201404244474"),"yyyyMMdd");
		Date date = beginOfDay(afterDaysSinceDate(new Date(), -30));
		System.out.println(idCardBirth);
		System.out.println(date);
		int days = DateTimeUtil.getBetweenDays(date,idCardBirth);
		System.out.println(days);
		System.out.println(DateTimeUtil.getBetweenDays(idCardBirth,new Date()));*/
		/*String bis = IdCardUtil.getBirthByIdCard("340621201404244474");
		Date babyBirth = DateTimeUtil.getFormatDate(bis);
		System.out.println(babyBirth);*/
		/*System.out.println(System.currentTimeMillis());
		String funcFlag = String.valueOf(System.currentTimeMillis());
		String tranNo = funcFlag.substring(5,funcFlag.length());
		System.out.println(tranNo);*/

		/*System.out.println(getMonthsDate(new Date(),-3));*/
	   /* System.out.println(getPreOrNex(new Date(),30));*/
	    String key = DateTimeUtil.getFormatDate(new Date(),"yyyy-MM-dd HH:mm")+"_"+32432;
	    String id = key.substring(key.lastIndexOf("_")+1,key.length());
	    System.out.println(Integer.parseInt(id));
	    System.out.println(key.substring(0,key.lastIndexOf("_")));
	    System.out.println(DateTimeUtil.getDateByString(key.substring(0,key.lastIndexOf("_")),"yyyy-MM-dd HH:mm"));
    }
}
